{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from glob import glob\n",
    "import random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "image\\andrew\\andrew1.jpg\n",
      "205\n"
     ]
    }
   ],
   "source": [
    "files = glob('image/*/*.jpg')\n",
    "print(files[0])\n",
    "print(len(files))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "random.seed(1)\n",
    "positive_pairs = []\n",
    "while len(positive_pairs)<10000:\n",
    "    j = random.randint(0,204)\n",
    "    k = random.randint(0,204)\n",
    "    if files[j].split('\\\\')[1] == files[k].split('\\\\')[1]:\n",
    "        positive_pairs.append(files[j])\n",
    "        positive_pairs.append(files[k])\n",
    "print(len(positive_pairs))\n",
    "positive_pairs = np.array(positive_pairs)\n",
    "positive_pairs = positive_pairs.reshape((5000,2))\n",
    "positive_pairs = pd.DataFrame(positive_pairs)\n",
    "positive_pairs.to_csv('positive_txt.txt',header=None,index=None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "random.seed(2)\n",
    "negative_pairs = []\n",
    "while len(negative_pairs)<10000:\n",
    "    j = random.randint(0,204)\n",
    "    k = random.randint(0,204)\n",
    "    if files[j].split('\\\\')[1] != files[k].split('\\\\')[1]:\n",
    "        negative_pairs.append(files[j])\n",
    "        negative_pairs.append(files[k])\n",
    "print(len(negative_pairs))\n",
    "negative_pairs = np.array(negative_pairs)\n",
    "negative_pairs = negative_pairs.reshape((5000,2))\n",
    "negative_pairs = pd.DataFrame(negative_pairs)\n",
    "negative_pairs.to_csv('negative_txt.txt',header=None,index=None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from keras.models import Model,Sequential\n",
    "from keras.layers import Input, Conv2D, Lambda, Dense, Flatten,Activation\n",
    "from keras.layers.normalization import BatchNormalization\n",
    "from keras.layers.pooling import MaxPooling2D, AveragePooling2D\n",
    "#from keras.initializers import glorot_uniform\n",
    "from keras.engine.topology import Layer\n",
    "from keras import backend as K\n",
    "import cv2\n",
    "import os\n",
    "import numpy as np\n",
    "#from numpy import genfromtxt\n",
    "import pandas as pd\n",
    "import tensorflow as tf\n",
    "\n",
    "#from keras.regularizers import l2\n",
    "from keras.optimizers import SGD,Adam,RMSprop\n",
    "from keras.losses import binary_crossentropy\n",
    "import numpy.random as rng\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.utils import shuffle\n",
    "\n",
    "\n",
    "%matplotlib inline\n",
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image\n",
    "\n",
    "dev_number = 8000\n",
    "batch_size = 128\n",
    "\n",
    "negative_pairs_file = open('negative_txt.txt', 'r')\n",
    "negative_pairs_lines = negative_pairs_file.readlines()\n",
    "positive_pairs_file = open('positive_txt.txt', 'r')\n",
    "positive_pairs_lines = positive_pairs_file.readlines()\n",
    "\n",
    "left_image_path_list = []\n",
    "right_image_path_list = []\n",
    "label_list = []\n",
    "\n",
    "for line in negative_pairs_lines:\n",
    "    left_right = line.split(',')\n",
    "    left_image_path_list.append(left_right[0])\n",
    "    right_image_path_list.append(left_right[1].strip('\\n'))\n",
    "    label_list.append(0)\n",
    "\n",
    "for line in positive_pairs_lines:\n",
    "    left_right = line.split(',')\n",
    "    left_image_path_list.append(left_right[0])\n",
    "    right_image_path_list.append(left_right[1].strip('\\n'))\n",
    "    label_list.append(1)\n",
    "\n",
    "left_image_path_list = np.asarray(left_image_path_list)\n",
    "right_image_path_list = np.asarray(right_image_path_list)\n",
    "label_list = np.asarray(label_list)\n",
    "\n",
    "np.random.seed(1)\n",
    "shuffle_index = np.random.permutation(np.arange(len(label_list)))\n",
    "left_shuffled = left_image_path_list[shuffle_index]\n",
    "right_shuffled = right_image_path_list[shuffle_index]\n",
    "label_shuffled = label_list[shuffle_index]\n",
    "\n",
    "left_train, left_dev = left_shuffled[:dev_number], left_shuffled[dev_number:]\n",
    "right_train, right_dev = right_shuffled[:dev_number], right_shuffled[dev_number:]\n",
    "label_train, label_dev = label_shuffled[:dev_number], label_shuffled[dev_number:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "num_pix = 72\n",
    "def vectorize_imgs(img_path_list):\n",
    "    image_arr_list = []\n",
    "    for img_path in img_path_list:\n",
    "        img = Image.open(img_path)\n",
    "        img = img.resize((num_pix,num_pix))\n",
    "        img_arr = np.asarray(img, dtype='float32')\n",
    "        image_arr_list.append(img_arr)\n",
    "        \n",
    "    return image_arr_list\n",
    "\n",
    "\n",
    "def get_image_array(left_image,right_image,label):\n",
    "    left = np.asarray(vectorize_imgs(left_image)) / 255.\n",
    "    right = np.asarray(vectorize_imgs(right_image)) / 255.\n",
    "    label = np.asarray(label)[:, np.newaxis]\n",
    "    return left,right,label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "left_arr, right_arr, label_arr = get_image_array(left_train, right_train, label_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "left_dev_arr, right_dev_arr, label_dev_arr = get_image_array(left_dev, right_dev, label_dev)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1733697"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "input_shape = (72, 72, 3)\n",
    "left_input = Input(input_shape)\n",
    "right_input = Input(input_shape)\n",
    "siamese_net = Sequential()\n",
    "siamese_net.add(Conv2D(32,(5,5),activation='relu',input_shape=input_shape))\n",
    "siamese_net.add(MaxPooling2D())\n",
    "siamese_net.add(Conv2D(64,(3,3),activation='relu'))\n",
    "siamese_net.add(MaxPooling2D())\n",
    "siamese_net.add(Conv2D(128,(3,3),activation='relu'))\n",
    "siamese_net.add(MaxPooling2D())\n",
    "siamese_net.add(Conv2D(256,(1,1),activation='relu'))\n",
    "siamese_net.add(Flatten())\n",
    "siamese_net.add(Dense(128,activation=\"sigmoid\"))\n",
    "\n",
    "encoded_l = siamese_net(left_input)\n",
    "encoded_r = siamese_net(right_input)\n",
    "L1_layer = Lambda(lambda tensors:K.abs(tensors[0] - tensors[1]))\n",
    "L1_distance = L1_layer([encoded_l, encoded_r])\n",
    "prediction = Dense(1,activation='sigmoid')(L1_distance)\n",
    "siamese_net = Model(inputs=[left_input,right_input],outputs=prediction)\n",
    "optimizer = Adam(0.00006)\n",
    "siamese_net.compile(loss=\"binary_crossentropy\",optimizer=optimizer,metrics=['acc'])\n",
    "siamese_net.count_params()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 8000 samples, validate on 2000 samples\n",
      "Epoch 1/50\n",
      "8000/8000 [==============================] - 9s 1ms/step - loss: 0.5253 - acc: 0.7378 - val_loss: 0.3728 - val_acc: 0.8580\n",
      "\n",
      "Epoch 00001: val_loss improved from inf to 0.37283, saving model to model.h5\n",
      "Epoch 2/50\n",
      "8000/8000 [==============================] - 4s 488us/step - loss: 0.2241 - acc: 0.9539 - val_loss: 0.1573 - val_acc: 0.9760\n",
      "\n",
      "Epoch 00002: val_loss improved from 0.37283 to 0.15735, saving model to model.h5\n",
      "Epoch 3/50\n",
      "8000/8000 [==============================] - 4s 488us/step - loss: 0.1294 - acc: 0.9774 - val_loss: 0.1167 - val_acc: 0.9805\n",
      "\n",
      "Epoch 00003: val_loss improved from 0.15735 to 0.11665, saving model to model.h5\n",
      "Epoch 4/50\n",
      "8000/8000 [==============================] - 4s 488us/step - loss: 0.0987 - acc: 0.9840 - val_loss: 0.0921 - val_acc: 0.9880\n",
      "\n",
      "Epoch 00004: val_loss improved from 0.11665 to 0.09209, saving model to model.h5\n",
      "Epoch 5/50\n",
      "8000/8000 [==============================] - 4s 486us/step - loss: 0.0745 - acc: 0.9892 - val_loss: 0.0783 - val_acc: 0.9880\n",
      "\n",
      "Epoch 00005: val_loss improved from 0.09209 to 0.07825, saving model to model.h5\n",
      "Epoch 6/50\n",
      "8000/8000 [==============================] - 4s 493us/step - loss: 0.0630 - acc: 0.9918 - val_loss: 0.0698 - val_acc: 0.9895\n",
      "\n",
      "Epoch 00006: val_loss improved from 0.07825 to 0.06983, saving model to model.h5\n",
      "Epoch 7/50\n",
      "8000/8000 [==============================] - 4s 485us/step - loss: 0.0551 - acc: 0.9931 - val_loss: 0.0650 - val_acc: 0.9900\n",
      "\n",
      "Epoch 00007: val_loss improved from 0.06983 to 0.06499, saving model to model.h5\n",
      "Epoch 8/50\n",
      "8000/8000 [==============================] - 4s 485us/step - loss: 0.0496 - acc: 0.9944 - val_loss: 0.0589 - val_acc: 0.9900\n",
      "\n",
      "Epoch 00008: val_loss improved from 0.06499 to 0.05892, saving model to model.h5\n",
      "Epoch 9/50\n",
      "8000/8000 [==============================] - 4s 485us/step - loss: 0.0444 - acc: 0.9960 - val_loss: 0.0542 - val_acc: 0.9905\n",
      "\n",
      "Epoch 00009: val_loss improved from 0.05892 to 0.05421, saving model to model.h5\n",
      "Epoch 10/50\n",
      "8000/8000 [==============================] - 4s 489us/step - loss: 0.0397 - acc: 0.9968 - val_loss: 0.0511 - val_acc: 0.9910\n",
      "\n",
      "Epoch 00010: val_loss improved from 0.05421 to 0.05112, saving model to model.h5\n",
      "Epoch 11/50\n",
      "8000/8000 [==============================] - 4s 484us/step - loss: 0.0375 - acc: 0.9971 - val_loss: 0.0503 - val_acc: 0.9905\n",
      "\n",
      "Epoch 00011: val_loss improved from 0.05112 to 0.05026, saving model to model.h5\n",
      "Epoch 12/50\n",
      "8000/8000 [==============================] - 4s 487us/step - loss: 0.0355 - acc: 0.9979 - val_loss: 0.0477 - val_acc: 0.9915\n",
      "\n",
      "Epoch 00012: val_loss improved from 0.05026 to 0.04770, saving model to model.h5\n",
      "Epoch 13/50\n",
      "8000/8000 [==============================] - 4s 484us/step - loss: 0.0331 - acc: 0.9984 - val_loss: 0.0457 - val_acc: 0.9915\n",
      "\n",
      "Epoch 00013: val_loss improved from 0.04770 to 0.04565, saving model to model.h5\n",
      "Epoch 14/50\n",
      "8000/8000 [==============================] - 4s 483us/step - loss: 0.0315 - acc: 0.9988 - val_loss: 0.0449 - val_acc: 0.9910\n",
      "\n",
      "Epoch 00014: val_loss improved from 0.04565 to 0.04486, saving model to model.h5\n",
      "Epoch 15/50\n",
      "8000/8000 [==============================] - 4s 488us/step - loss: 0.0300 - acc: 0.9986 - val_loss: 0.0442 - val_acc: 0.9910\n",
      "\n",
      "Epoch 00015: val_loss improved from 0.04486 to 0.04417, saving model to model.h5\n",
      "Epoch 16/50\n",
      "8000/8000 [==============================] - 4s 483us/step - loss: 0.0291 - acc: 0.9988 - val_loss: 0.0433 - val_acc: 0.9900\n",
      "\n",
      "Epoch 00016: val_loss improved from 0.04417 to 0.04329, saving model to model.h5\n",
      "Epoch 17/50\n",
      "8000/8000 [==============================] - 4s 487us/step - loss: 0.0282 - acc: 0.9988 - val_loss: 0.0420 - val_acc: 0.9905\n",
      "\n",
      "Epoch 00017: val_loss improved from 0.04329 to 0.04203, saving model to model.h5\n",
      "Epoch 18/50\n",
      "8000/8000 [==============================] - 4s 488us/step - loss: 0.0275 - acc: 0.9988 - val_loss: 0.0415 - val_acc: 0.9915\n",
      "\n",
      "Epoch 00018: val_loss improved from 0.04203 to 0.04153, saving model to model.h5\n",
      "Epoch 19/50\n",
      "8000/8000 [==============================] - 4s 487us/step - loss: 0.0268 - acc: 0.9988 - val_loss: 0.0407 - val_acc: 0.9920\n",
      "\n",
      "Epoch 00019: val_loss improved from 0.04153 to 0.04069, saving model to model.h5\n",
      "Epoch 20/50\n",
      "8000/8000 [==============================] - 4s 484us/step - loss: 0.0260 - acc: 0.9988 - val_loss: 0.0400 - val_acc: 0.9910\n",
      "\n",
      "Epoch 00020: val_loss improved from 0.04069 to 0.04002, saving model to model.h5\n",
      "Epoch 21/50\n",
      "8000/8000 [==============================] - 4s 485us/step - loss: 0.0254 - acc: 0.9989 - val_loss: 0.0396 - val_acc: 0.9905\n",
      "\n",
      "Epoch 00021: val_loss improved from 0.04002 to 0.03959, saving model to model.h5\n",
      "Epoch 22/50\n",
      "8000/8000 [==============================] - 4s 492us/step - loss: 0.0249 - acc: 0.9989 - val_loss: 0.0390 - val_acc: 0.9905\n",
      "\n",
      "Epoch 00022: val_loss improved from 0.03959 to 0.03902, saving model to model.h5\n",
      "Epoch 23/50\n",
      "8000/8000 [==============================] - 4s 483us/step - loss: 0.0245 - acc: 0.9990 - val_loss: 0.0386 - val_acc: 0.9915\n",
      "\n",
      "Epoch 00023: val_loss improved from 0.03902 to 0.03858, saving model to model.h5\n",
      "Epoch 24/50\n",
      "8000/8000 [==============================] - 4s 490us/step - loss: 0.0240 - acc: 0.9990 - val_loss: 0.0379 - val_acc: 0.9920\n",
      "\n",
      "Epoch 00024: val_loss improved from 0.03858 to 0.03795, saving model to model.h5\n",
      "Epoch 25/50\n",
      "8000/8000 [==============================] - 4s 486us/step - loss: 0.0235 - acc: 0.9990 - val_loss: 0.0373 - val_acc: 0.9930\n",
      "\n",
      "Epoch 00025: val_loss improved from 0.03795 to 0.03728, saving model to model.h5\n",
      "Epoch 26/50\n",
      "8000/8000 [==============================] - 4s 483us/step - loss: 0.0231 - acc: 0.9990 - val_loss: 0.0367 - val_acc: 0.9930\n",
      "\n",
      "Epoch 00026: val_loss improved from 0.03728 to 0.03673, saving model to model.h5\n",
      "Epoch 27/50\n",
      "8000/8000 [==============================] - 4s 476us/step - loss: 0.0227 - acc: 0.9990 - val_loss: 0.0367 - val_acc: 0.9930\n",
      "\n",
      "Epoch 00027: val_loss improved from 0.03673 to 0.03667, saving model to model.h5\n",
      "Epoch 28/50\n",
      "8000/8000 [==============================] - 4s 477us/step - loss: 0.0225 - acc: 0.9990 - val_loss: 0.0362 - val_acc: 0.9930\n",
      "\n",
      "Epoch 00028: val_loss improved from 0.03667 to 0.03625, saving model to model.h5\n",
      "Epoch 29/50\n",
      "8000/8000 [==============================] - 4s 487us/step - loss: 0.0222 - acc: 0.9990 - val_loss: 0.0361 - val_acc: 0.9940\n",
      "\n",
      "Epoch 00029: val_loss improved from 0.03625 to 0.03605, saving model to model.h5\n",
      "Epoch 30/50\n",
      "8000/8000 [==============================] - 4s 483us/step - loss: 0.0220 - acc: 0.9991 - val_loss: 0.0359 - val_acc: 0.9940\n",
      "\n",
      "Epoch 00030: val_loss improved from 0.03605 to 0.03586, saving model to model.h5\n",
      "Epoch 31/50\n",
      "8000/8000 [==============================] - 4s 484us/step - loss: 0.0218 - acc: 0.9990 - val_loss: 0.0357 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00031: val_loss improved from 0.03586 to 0.03574, saving model to model.h5\n",
      "Epoch 32/50\n",
      "8000/8000 [==============================] - 4s 486us/step - loss: 0.0216 - acc: 0.9991 - val_loss: 0.0356 - val_acc: 0.9930\n",
      "\n",
      "Epoch 00032: val_loss improved from 0.03574 to 0.03555, saving model to model.h5\n",
      "Epoch 33/50\n",
      "8000/8000 [==============================] - 4s 485us/step - loss: 0.0214 - acc: 0.9991 - val_loss: 0.0353 - val_acc: 0.9930\n",
      "\n",
      "Epoch 00033: val_loss improved from 0.03555 to 0.03528, saving model to model.h5\n",
      "Epoch 34/50\n",
      "8000/8000 [==============================] - 4s 485us/step - loss: 0.0211 - acc: 0.9991 - val_loss: 0.0349 - val_acc: 0.9930\n",
      "\n",
      "Epoch 00034: val_loss improved from 0.03528 to 0.03492, saving model to model.h5\n",
      "Epoch 35/50\n",
      "8000/8000 [==============================] - 4s 486us/step - loss: 0.0209 - acc: 0.9993 - val_loss: 0.0347 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00035: val_loss improved from 0.03492 to 0.03469, saving model to model.h5\n",
      "Epoch 36/50\n",
      "8000/8000 [==============================] - 4s 492us/step - loss: 0.0207 - acc: 0.9993 - val_loss: 0.0345 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00036: val_loss improved from 0.03469 to 0.03454, saving model to model.h5\n",
      "Epoch 37/50\n",
      "8000/8000 [==============================] - 4s 491us/step - loss: 0.0206 - acc: 0.9993 - val_loss: 0.0344 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00037: val_loss improved from 0.03454 to 0.03445, saving model to model.h5\n",
      "Epoch 38/50\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8000/8000 [==============================] - 4s 482us/step - loss: 0.0204 - acc: 0.9993 - val_loss: 0.0342 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00038: val_loss improved from 0.03445 to 0.03419, saving model to model.h5\n",
      "Epoch 39/50\n",
      "8000/8000 [==============================] - 4s 487us/step - loss: 0.0203 - acc: 0.9993 - val_loss: 0.0341 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00039: val_loss improved from 0.03419 to 0.03409, saving model to model.h5\n",
      "Epoch 40/50\n",
      "8000/8000 [==============================] - 4s 489us/step - loss: 0.0202 - acc: 0.9993 - val_loss: 0.0340 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00040: val_loss improved from 0.03409 to 0.03399, saving model to model.h5\n",
      "Epoch 41/50\n",
      "8000/8000 [==============================] - 4s 481us/step - loss: 0.0202 - acc: 0.9993 - val_loss: 0.0339 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00041: val_loss improved from 0.03399 to 0.03386, saving model to model.h5\n",
      "Epoch 42/50\n",
      "8000/8000 [==============================] - 4s 484us/step - loss: 0.0201 - acc: 0.9993 - val_loss: 0.0338 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00042: val_loss improved from 0.03386 to 0.03380, saving model to model.h5\n",
      "Epoch 43/50\n",
      "8000/8000 [==============================] - 4s 485us/step - loss: 0.0200 - acc: 0.9993 - val_loss: 0.0337 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00043: val_loss improved from 0.03380 to 0.03373, saving model to model.h5\n",
      "Epoch 44/50\n",
      "8000/8000 [==============================] - 4s 481us/step - loss: 0.0199 - acc: 0.9994 - val_loss: 0.0337 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00044: val_loss improved from 0.03373 to 0.03365, saving model to model.h5\n",
      "Epoch 45/50\n",
      "8000/8000 [==============================] - 4s 485us/step - loss: 0.0199 - acc: 0.9993 - val_loss: 0.0336 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00045: val_loss improved from 0.03365 to 0.03357, saving model to model.h5\n",
      "Epoch 46/50\n",
      "8000/8000 [==============================] - 4s 487us/step - loss: 0.0199 - acc: 0.9994 - val_loss: 0.0335 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00046: val_loss improved from 0.03357 to 0.03351, saving model to model.h5\n",
      "Epoch 47/50\n",
      "8000/8000 [==============================] - 4s 484us/step - loss: 0.0198 - acc: 0.9993 - val_loss: 0.0335 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00047: val_loss improved from 0.03351 to 0.03350, saving model to model.h5\n",
      "Epoch 48/50\n",
      "8000/8000 [==============================] - 4s 487us/step - loss: 0.0198 - acc: 0.9994 - val_loss: 0.0334 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00048: val_loss improved from 0.03350 to 0.03342, saving model to model.h5\n",
      "Epoch 49/50\n",
      "8000/8000 [==============================] - 4s 482us/step - loss: 0.0197 - acc: 0.9994 - val_loss: 0.0333 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00049: val_loss improved from 0.03342 to 0.03334, saving model to model.h5\n",
      "Epoch 50/50\n",
      "8000/8000 [==============================] - 4s 485us/step - loss: 0.0197 - acc: 0.9994 - val_loss: 0.0333 - val_acc: 0.9935\n",
      "\n",
      "Epoch 00050: val_loss improved from 0.03334 to 0.03332, saving model to model.h5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x229b5e59cf8>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from keras.callbacks import LearningRateScheduler, EarlyStopping\n",
    "from keras.callbacks import ModelCheckpoint\n",
    "\n",
    "batch_size = 64\n",
    "annealer = LearningRateScheduler(lambda x: 1e-3 * 0.9 ** x)\n",
    "earlystop = EarlyStopping(patience=10)\n",
    "modelsave = ModelCheckpoint(\n",
    "    filepath='model.h5', save_best_only=True, verbose=1)\n",
    "siamese_net.fit(\n",
    "    [left_arr, right_arr],  label_arr, batch_size=batch_size,\n",
    "    epochs=50, \n",
    "    validation_data=([left_dev_arr, right_dev_arr], label_dev_arr),\n",
    "    callbacks=[annealer, earlystop, modelsave])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def img_to_encoding(image_path1,image_path2,model):\n",
    "    img1 = cv2.imread(image_path1)\n",
    "    img1 = cv2.resize(img1, (72,72))\n",
    "    img2 = cv2.imread(image_path2)\n",
    "    img2 = cv2.resize(img2, (72,72))\n",
    "    x_train1 = np.array([img1])/255\n",
    "    x_train2 = np.array([img2])/255\n",
    "    result = model.predict([x_train1,x_train2])\n",
    "    return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "database = {}\n",
    "database[\"loulou\"] = \"image/loulou/1.jpg\"\n",
    "database[\"pei\"] = \"image/pei/pei1.jpg\"\n",
    "database[\"han\"] = \"image/han/han21.jpg\"\n",
    "database[\"andrew\"] = \"image/andrew/andrew12.jpg\"\n",
    "database[\"liuyifei\"] = \"image/liuyifei/fei1.jpg\"\n",
    "database[\"xidada\"] = \"image/xidada/xi2.jpg\"\n",
    "database[\"huge\"] = \"image/huge/hu1.jpg\"   \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def who_is_it(test_image_path,database,model):\n",
    "    max_pro = 0\n",
    "    dis = []\n",
    "    for (name, path) in database.items():\n",
    "        pro = img_to_encoding(test_image_path,path,model)\n",
    "        dis.append(pro)\n",
    "        if pro>max_pro:\n",
    "            max_pro = pro\n",
    "            identity = name\n",
    "    if max_pro < 0.2:\n",
    "        print(\"Not in the database.\")\n",
    "    else:\n",
    "        print (\"it's \" + str(identity) + \", the distance is \" + str(max_pro))\n",
    "    print(dis)   \n",
    "    return max_pro, identity,dis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "it's loulou, the distance is [[ 0.94823778]]\n",
      "[array([[ 0.94823778]], dtype=float32), array([[ 0.00016784]], dtype=float32), array([[ 0.00044473]], dtype=float32), array([[ 0.12815975]], dtype=float32), array([[  7.64963293e-09]], dtype=float32), array([[  4.93606720e-08]], dtype=float32), array([[  1.75218346e-07]], dtype=float32)]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(array([[ 0.94823778]], dtype=float32),\n",
       " 'loulou',\n",
       " [array([[ 0.94823778]], dtype=float32),\n",
       "  array([[ 0.00016784]], dtype=float32),\n",
       "  array([[ 0.00044473]], dtype=float32),\n",
       "  array([[ 0.12815975]], dtype=float32),\n",
       "  array([[  7.64963293e-09]], dtype=float32),\n",
       "  array([[  4.93606720e-08]], dtype=float32),\n",
       "  array([[  1.75218346e-07]], dtype=float32)])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "who_is_it(\"test/2.jpg\", database, siamese_net)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
